#ifndef JSON_H
#define JSON_H

#include <string>
#include <map>
#include <vector>

class json_t {
    public:
        typedef enum {
            UNDEF,
            OBJ,
            STRING,
            NUM,
            BOOL,
            NULLVALUE,
            ARRAY,
        } type_t;
    private:
        long readp{0};
        bool valid{false};
        type_t type{UNDEF};
        std::vector<std::string> item_key;
        std::map<std::string, json_t> item;
        std::string value_string;
        int value_num;
        std::vector<json_t> value_array;
        long _read(char *buf, long &p, long size);
        bool l(void * __fd, ssize_t &size, bool (*check_char)(void * __fd, ssize_t &size, char &c, const char expect[]), bool (*read_char)(void * __fd, ssize_t &size, char &c));
    public:
        bool load(std::string fn);
        bool sock_recv(int __fd, ssize_t &size);
        json_t &operator[](const char * key);
        json_t &operator[](const std::string key);
        json_t &operator[](size_t i);
        std::string key(int i);
        size_t size();
        type_t gettype();
        std::string &string();
        int num();
        bool b();
        std::vector<json_t> &array();
        bool is_valid();
        void clear();
        json_t &append_array();
        bool append_array(json_t &value);
        bool append_array(int value);
        bool append_array(std::string value);
        int operator = (int value);
        std::string operator = (std::string value);
        const char *operator = (const char *value);
        void seek(long offset, int whence);
        long read(char *buf, long size);
};

void print_json(json_t &json, int indent = 0, bool doindent = false);

#endif
